﻿using System;
using System.Linq;
using QDT.Cache;
using QDT.Common;
using QDT.Core.Deals;
using QDT.Core.Members;
using QDT.Core.Projects;

namespace QDT.Services.Members
{
    public partial class UserService
    {
        public UserSta UserSta(string username)
        {
            const string cacheKey = "User/UserSta/U_{0}/";
            var cache = QDTCache.GetCacheService();
            var sta = cache.RetrieveObject(cacheKey.FormatWith(username.Hash())) as UserSta;
            if (sta == null)
            {
                var user = DbProvider.D<User>().FirstOrDefault(x => x.UserName == username);
                if (user == null) throw new Exception("无效账户");
                user.UserSta = sta = DbProvider.GetByID<UserSta>(user.ID) ?? CreateSta(user);
                if (user.UserAccount.LenderOver || user.UserAccount.BorrowerOver) sta = UpdateSta(user);
                cache.AddObject(cacheKey.FormatWith(user.UserName.Hash()), sta, 30);
            }
            return sta;
        }

        public bool UserSta(User user)
        {
            try
            {
                var sta = DbProvider.GetByID<UserSta>(user.ID);
                CalculateLender(sta);
                DbProvider.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void ExpireSta(User user, ExpireType type)
        {
            if (type == ExpireType.Lender) user.UserAccount.LenderOver = true;
            if (type == ExpireType.Borrower) user.UserAccount.BorrowerOver = true;
        }

        protected UserSta CreateSta(User user)
        {
            var sta = new UserSta(user);
            DbProvider.Add(sta);
            DbProvider.SaveChanges();
            return sta;
        }

        protected UserSta UpdateSta(User user)
        {
            var sta = user.UserSta;
            if (user.UserAccount.LenderOver)
            {
                CalculateLender(sta);
                user.UserAccount.LenderOver = false;
            }
            if (user.UserAccount.BorrowerOver)
            {
                CalculateBorrower(sta);
                user.UserAccount.BorrowerOver = false;
            }
            DbProvider.SaveChanges();
            return sta;
        }

        protected UserSta CalculateLender(UserSta sta)
        {
            var credits = DbProvider.D<Credit>().Where(x => x.UserID == sta.UserId);
            var tcredits = DbProvider.D<Credit>().Where(x => x.UserID == sta.UserId && x.Money>0);

            sta.LoadEarnings = credits.Any(x => x.RepayEarning > 0) ? credits.Where(x => x.RepayEarning > 0).Sum(x => x.RepayEarning) : 0;
            sta.LoadWaitRepayMoney = credits.Any(x => x.InnerStatus < 4 && x.WaitRepayPrincipal > 0) ? credits.Where(x => !x.IsRepay && x.WaitRepayPrincipal > 0).Sum(x => x.WaitRepayPrincipal) : 0;
            sta.LoadWaitRepayEarnings = credits.Any(x => x.InnerStatus < 4 && x.WaitRepayEarning > 0) ? credits.Where(x => !x.IsRepay && x.WaitRepayEarning > 0).Sum(x => x.WaitRepayEarning) : 0;
            sta.TotalLoadMoney = tcredits.Any() ? tcredits.Sum(x => x.Money) : 0;

            return sta;
        }

        protected UserSta CalculateBorrower(UserSta sta)
        {
            var projects = DbProvider.D<Project>().Where(x => x.UserID == sta.UserId && x.IsEffect && !x.IsDelete).ToList();
            sta.BorrowAmount = projects.Where(x => x.InnerStatus > 2).Sum(x => x.BorrowAmount);
            sta.SuccessDealCount = projects.Count(x => x.InnerStatus > 2);
            sta.ProgressDealCount = projects.Count(x => x.Status == ProjectStatus.Progress);
            sta.RepaidDealCount = projects.Count(x => x.Status == ProjectStatus.Repaid);

            return sta;
        }

    }
}
